﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;

namespace JProfiler
{
    public class JProfilerWindow : EditorWindow
    {
        bool m_ShowMarkerTable = true;
        bool m_ShowFrameSummary = true;
        JProfileTable m_ProfileTable;
        MultiColumnHeaderState m_ProfileMulticolumnHeaderState;

        [MenuItem("Tools/CustomerProfiler")]
        static void Init()
        {
            var window = GetWindow<JProfilerWindow>("JProfiler");
            window.minSize = new Vector2(LayoutSize.MinWindowWidth, LayoutSize.MinWindowHeight);
            window.position.size.Set(LayoutSize.WindowWidth, LayoutSize.WindowHeight);
            window.Show();
        }

        private void OnEnable()
        {
            int sortedColumn = (int)MyColumns.TotalCount;
            bool sortAscending = false;

            if (m_ProfileMulticolumnHeaderState != null)
            {
                if (m_ProfileMulticolumnHeaderState.sortedColumnIndex >= 0)
                {
                    sortedColumn = m_ProfileMulticolumnHeaderState.sortedColumnIndex;
                    if (sortedColumn >= 0 && sortedColumn < m_ProfileMulticolumnHeaderState.columns.Length)
                        sortAscending = m_ProfileMulticolumnHeaderState.columns[sortedColumn].sortedAscending;
                }
            }

            m_ProfileMulticolumnHeaderState = JProfileTable.CreateDefaultMultiColumnHeaderState();
            var multiColumnHeader = new MultiColumnHeader(m_ProfileMulticolumnHeaderState);
            multiColumnHeader.SetSorting(sortedColumn, sortAscending);
            multiColumnHeader.ResizeToFit();
            m_ProfileTable = new JProfileTable(multiColumnHeader, this);
        }

        private float m_LastTime = 0.0f;
        private void Update()
        {
            if(Time.time - m_LastTime > 1.0f)
            {
                if(m_ProfileTable != null)
                {
                    m_ProfileTable.Reload();
                }
                m_LastTime = Time.time;
            }
        }

        void OnGUI()
        {
            if (Event.current.type != EventType.MouseMove)
            {
                Draw();
            }

            ProcessInput();
        }

        void ProcessInput()
        {

        }

        void Draw()
        {
            if (JProfiler.Instance == null)
            {
                this.Close();
                return;
            }
            GUI.enabled = true;
            EditorGUILayout.BeginVertical();
            DrawToolbar();
            DrawAnalysis();

            EditorGUILayout.EndVertical();
        }

        public static void Export(JProfileData data)
        {
            var list = data.ItemDatas;
            string path = EditorUtility.SaveFilePanel("导出数据", "", "JProfilerData.txt", "txt");
            if (path.Length != 0)
            {
                using (StreamWriter file = new StreamWriter(path))
                {
                    string column = "";
                    column += "Name\t";
                    column += "Type\t";
                    column += "TotalCount\t";
                    column += "CountPerSec\t";
                    column += "CountPerMin\t";
                    column += "TotalCost\t";
                    column += "CostAve\t";
                    column += "CostMin\t";
                    column += "CostMax\t";
                    column += "TotalMem\t";
                    column += "MemAve\t";
                    column += "MemMin\t";
                    column += "MemMax";
                    file.WriteLine(column);

                    var itemList = data.ItemDatas;
                    foreach (JItemData item in itemList.Values)
                    {
                        string line = "";
                        for(int i  = 0; i < 13; i++)
                        {
                            line += item.GetNameByColumn(i);
                            if (i < 12) line += "\t";
                        }
                        file.WriteLine(line);
                    }
                }
            }
        }

        void DrawToolbar()
        {
            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            EditorGUILayout.Separator();
            bool lastEnabled = GUI.enabled;
            bool enabled = GUI.enabled;
            
            bool isRunning = GUILayout.Toggle(JProfiler.Instance.IsRunning, Styles.running, GUILayout.Width(50));
            JProfiler.Instance.IsRunning = isRunning;

            /*
            if (GUILayout.Button(Styles.clear, EditorStyles.toolbarButton, GUILayout.Width(50)))
            {
                JProfiler.Instance.ClearRecords();
                EditorGUIUtility.ExitGUI();
            }
            */

                    EditorGUILayout.Separator();

            if (GUILayout.Button(Styles.export, EditorStyles.toolbarButton, GUILayout.Width(50)))
            {
                Export(JProfiler.Instance.Data);
                EditorGUIUtility.ExitGUI();
            }

            GUI.enabled = lastEnabled;

            EditorGUILayout.Separator();

            GUILayout.FlexibleSpace();

            EditorGUILayout.EndHorizontal();
        }

        bool BoldFoldout(bool toggle, GUIContent content)
        {
            GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout);
            foldoutStyle.fontStyle = FontStyle.Bold;
            return EditorGUILayout.Foldout(toggle, content, true, foldoutStyle);
        }

        void DrawSummary()
        {
            EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.WidthRHS));

            EditorGUILayout.HelpBox(Styles.helpText, MessageType.Info);

            bool lastShowFrameSummary = m_ShowFrameSummary;
            m_ShowFrameSummary = BoldFoldout(m_ShowFrameSummary, Styles.summary);
            JProfileData data = JProfiler.Instance.Data;
            if (m_ShowFrameSummary)
            {
                EditorGUILayout.BeginVertical();
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField(string.Format("StartTime: {0}", data.StartTime), GUILayout.Width(200));
                EditorGUILayout.LabelField(string.Format("EndTime: {0}", data.EndTime), GUILayout.Width(200));
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.LabelField(string.Format("Totals: {0}", JProfiler.Instance.Data.GetCount()), GUILayout.Width(100));
                TimeSpan delta = data.EndTime - data.StartTime;
                EditorGUILayout.LabelField(string.Format("Time: {0}h{1}m{2}s", delta.Hours, delta.Minutes, delta.Seconds), GUILayout.Width(200));
                EditorGUILayout.EndVertical();
            }
            EditorGUILayout.EndVertical();
        }

        public void UpdateData()
        {
            if(m_ProfileTable != null)
            {
                m_ProfileTable.Reload();
            }
        }


        void DrawAnalysis()
        {
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.BeginVertical();

            if (m_ProfileTable != null)
            {
                m_ShowMarkerTable = BoldFoldout(m_ShowMarkerTable, Styles.profileTitle);
                if (m_ShowMarkerTable)
                {
                    {
                        Rect r = EditorGUILayout.GetControlRect(GUILayout.ExpandHeight(true));

                        float scrollBarWidth = GUI.skin.verticalScrollbar.fixedWidth +
                            GUI.skin.verticalScrollbar.border.horizontal +
                            GUI.skin.verticalScrollbar.margin.horizontal +
                            GUI.skin.verticalScrollbar.padding.horizontal;
                        scrollBarWidth += LayoutSize.ScrollBarPadding;

                        Rect clipRect = new Rect(r.x, m_ProfileTable.state.scrollPos.y,
                            r.width - scrollBarWidth,
                            r.height -
                            (m_ProfileTable.multiColumnHeader.height + GUI.skin.box.padding.top) -
                            (m_ProfileTable.ShowingHorizontalScroll
                                ? (scrollBarWidth - LayoutSize.ScrollBarPadding)
                                : 0));
                        m_ProfileTable.OnGUI(r);
                    }
                }
            }
            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical(GUILayout.Width(LayoutSize.WidthRHS));
            GUILayout.Space(4);
            DrawSummary();
            EditorGUILayout.EndVertical();

            EditorGUILayout.EndHorizontal();
        }
    }
}
#endif